﻿﻿//------------------------------------------------------------------------------
// <copyright file="Common.cs" company="Microsoft">
//
//      Copyright 2013 Microsoft Corporation 
//
//      Licensed under the Microsoft Public License (Ms-PL). 
//      You may not use this file except in compliance with the License.
//
//      Unless required by applicable law or agreed to in writing, software 
//      distributed under the License is distributed on an "AS IS" BASIS,
//      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
//      See the License for the specific language governing permissions and 
//      limitations under the License. 
//
// </copyright>
﻿//------------------------------------------------------------------------------

 namespace MyOpenXmlHyperLink
{
    using System;
    using System.Globalization;
    using System.Linq;
    using DocumentFormat.OpenXml.Spreadsheet;
    public class MyHyperlinks
    {
        public static void AddHyperlink(string hyperlink, int row, string column, Worksheet openXmlWorksheet)
        {
            if (openXmlWorksheet == null)
            {
                throw new ArgumentNullException("openXmlWorksheet");
            }

            var url = new Uri(hyperlink, UriKind.Absolute);

            var reference = String.Format(CultureInfo.InvariantCulture, "{0}{1}", column, row);
            var hyperlinks = GetHyperlinks(openXmlWorksheet);
            var existingHyperlink = FindHyperlink(reference, hyperlinks);

            var hyperlinkId = string.Empty;
            if (existingHyperlink == null)
            {
                hyperlinkId = "hlId_" + Guid.NewGuid().GetHashCode();
                var newHyperlink = new Hyperlink()
                {
                    Reference = reference,
                    Id = hyperlinkId
                };

                hyperlinks.Append(newHyperlink);
            }
            else
            {
                hyperlinkId = existingHyperlink.Id;
                openXmlWorksheet.WorksheetPart.DeleteReferenceRelationship(hyperlinkId);
            }

            openXmlWorksheet.WorksheetPart.AddHyperlinkRelationship(url, true, hyperlinkId);
        }

        public static void RemoveHyperlink(int row, string column, Worksheet openXmlWorksheet)
        {
            if (openXmlWorksheet == null)
            {
                throw new ArgumentNullException("openXmlWorksheet");
            }

            var reference = String.Format(CultureInfo.InvariantCulture, "{0}{1}", column, row);
            var hyperlinks = GetHyperlinks(openXmlWorksheet, false);
            if (hyperlinks == null)
            {
                return;
            }

            var existingHyperlink = FindHyperlink(reference, hyperlinks);
            if (existingHyperlink == null)
            {
                return;
            }

            var hyperlinkId = existingHyperlink.Id;
            openXmlWorksheet.WorksheetPart.DeleteReferenceRelationship(hyperlinkId);
            hyperlinks.RemoveChild(existingHyperlink);
        }

        private static Hyperlinks GetHyperlinks(Worksheet fromWorksheet, bool createIfNotFound = true)
        {
            if (fromWorksheet == null)
            {
                throw new ArgumentNullException("fromWorksheet");
            }

            var hyperLinks = fromWorksheet.GetFirstChild<Hyperlinks>();
            if (hyperLinks == null && createIfNotFound)
            {
                hyperLinks = new Hyperlinks();
                OpenXmlHelper.Common.AppendChild(typeof(Hyperlinks), hyperLinks, fromWorksheet);
            }

            return hyperLinks;
        }

        private static Hyperlink FindHyperlink(string cellReference, Hyperlinks hyperlinks)
        {
            return hyperlinks.FirstOrDefault(t => (t is Hyperlink) && (t as Hyperlink).Reference.Value.Equals(cellReference, StringComparison.Ordinal)) as Hyperlink;
        }
    }
}
